#include "frame_thread_pool.h"

#include "mysql_build.h"
#include "log.h"



int exitPipe[2]; // handler只能访问全局的数据

void handler(int signum) {
	printf("Parent got signal, signum = %d\n", signum);
	write(exitPipe[1], "1", 1);
}

// ./server 192.168.142.128 12345 3 mysql密码
// ./server 192.168.142.128 12345 3 ""
int main(int argc, char *argv[]) {
	ARGS_CHECK(argc, 5);
	pipe(exitPipe);

	pid_t pid = fork();
	if (pid != 0) {
		//printf("I am parent, pid = %d\n", getpid());
		close(exitPipe[0]); // 父进程关闭管道的读端
		signal(SIGUSR1, handler);
		wait(NULL);
		printf("Parent is going to exit!\n");
		exit(0);
	}
	//printf("I am child, pid = %d\n", getpid());
	close(exitPipe[1]);  // 子进程关闭写端

	// 建立数据库
	MYSQL *mysql = mysql_init(NULL);
	setupDatabase(mysql, argv[4]);

	// 建立用户空间，3期
	buildUserSpace();

	// 建线程池
	threadPool_t threadPool;
	int workerNumber = atoi(argv[3]);
	threadPoolInit(&threadPool, workerNumber, mysql);

	// 建子线程
	makeWorker(&threadPool);

	// tcp
	int sockfd = tcpInit(argv[1], argv[2]);
	// epoll
	int epfd = epoll_create(1);
	epollAdd(epfd, sockfd);
	epollAdd(epfd, exitPipe[0]);

	struct epoll_event readySet[1024];
	while (1) {
		int readyNum = epoll_wait(epfd, readySet, 1024, -1);
		for (int i = 0; i < readyNum; i++) {
			if (readySet[i].data.fd == sockfd) {
				int netfd = accept(sockfd, NULL, NULL);

				pthread_mutex_lock(&threadPool.mutex);
				printf("I am master, I got a netfd = %d\n", netfd);
				enQueue(&threadPool.taskQueue, netfd);
				pthread_mutex_unlock(&threadPool.mutex);
				pthread_cond_broadcast(&threadPool.cond);
			} else if (readySet[i].data.fd == exitPipe[0]) {
				printf("threadPool is going to exit!\n");

				pthread_mutex_lock(&threadPool.mutex);
				threadPool.exitFlag = 1;
				pthread_mutex_unlock(&threadPool.mutex);
				pthread_cond_broadcast(&threadPool.cond);

				for (int j = 0; j < workerNumber; j++) {
					pthread_join(threadPool.tidArr.arr[j], NULL);
				}
				threadPoolFree(&threadPool);
				close(sockfd);

				printf("All threads have exited.\n");
				exit(0);
			}
		}
	}

	mysql_close(mysql);
	close(sockfd);

	return 0;
}
